/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2015 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = testtools_receive.c                                */
/*  NOTE      = 接收协议分析器返回的数据并保存到文件中             */
/*  DATE      = 2015/11/03 by guojq                                */
/*******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h> 
#include <errno.h>

#include "frcomm.h"
#include "frlist.h"
#include "test_comm.h"

extern char *g_p_dumpfile;
extern char *g_p_save_file;

static int __save_file(char *p_buff, char *p_out_file)
{
    FILE *fp = NULL;
    
    fp = fopen(p_out_file, "a");
    if (fp == NULL)
    {
        printf("open file %s error\n", p_out_file);
        return FR_FAIL;
    }
    fwrite(p_buff, strlen(p_buff), 1, fp);
    
    fclose(fp);
    return FR_SUCC;
}

static int __do_receive(int i_sockfd, char *p_out_file, int i_timeout)
{
    int i_recv = 0, i_len = 0;
    int i_safe = 0, i_loop = 2;
    int i_client_fd = 0;
    struct sockaddr_in from;
    char recvbuf[1024];
    fd_set read_flags;
    struct timeval to;

    i_len = sizeof(from);	/*发送ping应答消息的主机IP*/
    recvbuf[0] = '\0';
    FD_ZERO(&read_flags);
	FD_SET(i_sockfd, &read_flags);
    to.tv_sec = i_timeout; 
	to.tv_usec = 0; 

    while (i_loop)
    {
        if (select(i_sockfd + 1, &read_flags, 0, 0, &to) >= 0)
        {
            if(FD_ISSET(i_sockfd, &read_flags))
            {
                if( (i_client_fd = accept(i_sockfd, (struct sockaddr*)NULL, NULL)) == -1)
                {  
                    printf("accept socket error: %s(errno: %d)",strerror(errno),errno);  
                    return FR_FAIL;
                }
                i_safe++;
                while (1)
                {
                    memset(recvbuf, 0x00, sizeof(recvbuf));
                    if((i_recv = recv(i_client_fd, recvbuf, sizeof(recvbuf) - 1, 0))<0)
                    {	
                        if (i_safe > 1000)
                        {
                            close(i_client_fd);
                            return FR_FAIL;
                        }
                        printf("recv err [%d] %s\n", i_recv, strerror(errno));
                        return FR_FAIL;
                    }
                    else if (i_recv == 0)
                    {
                        if (__save_file("\n", p_out_file) != FR_SUCC)
                        {
                            close(i_client_fd);
                            return FR_FAIL;
                        }
                        break;
                    }
                    //接收到的数据写到文件中
                    if (__save_file(recvbuf, p_out_file) != FR_SUCC)
                    {
                        close(i_client_fd);
                        return FR_FAIL;
                    }
                }
                close(i_client_fd);
                continue;
            }
            i_loop--;
            
            to.tv_sec = i_timeout;
        }
    }
    
    return FR_SUCC;
}

int testtools_receive(int i_port, int i_timeout)
{
    int i_sockfd = 0;
    int i_ret = 0;
    struct sockaddr_in sin;
    
    i_sockfd = socket(PF_INET,SOCK_STREAM,0);
    if (i_sockfd < 0)
    {
        printf("socket error\n");
        return FR_FAIL;
    }
    
    bzero(&sin,sizeof(sin));// 初始化 然后是设置套接字
    sin.sin_family = AF_INET;//协议族，在socket编程中只能是AF_INET(TCP/IP协议族)
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = htons(i_port);
    
    if(bind(i_sockfd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
    {
        printf("socket bind error\n");
        return FR_FAIL;
    }
    if( listen(i_sockfd, 10) == -1)
    {
        printf("socket listen error\n");
        return FR_FAIL;
    }
    
    i_ret = __do_receive(i_sockfd, g_p_save_file, i_timeout);
    if (i_ret != FR_SUCC)
    {
        close(i_sockfd);
        return FR_FAIL;
    }
    
    close(i_sockfd);
    
    return FR_SUCC;
}

